package dominio.controlador;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.beanlib.CollectionPropertyName;
import net.sf.beanlib.hibernate3.Hibernate3BeanReplicator;
import net.sf.beanlib.spi.BeanMethodFinder;
import net.sf.beanlib.spi.BeanPopulatable;
import net.sf.beanlib.spi.DetailedBeanPopulatable;
import net.sf.beanlib.utils.BeanUtils;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import util.HibernateUtil;
import dominio.modelo.Comentario;
import dominio.modelo.Filme;
import dominio.modelo.Genero;
import dominio.modelo.Usuario;

public class CtrlPrincipal {
	
	private ServletContext servletContext;
	private HttpServletRequest request;
	private HttpServletResponse response;

	public CtrlPrincipal(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
		this.servletContext = servletContext;
		this.request = request;
		this.response = response;
	}
	
	public List<Filme> carregarListaFilmesPorRanking() {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Filme.class);
		criteria.addOrder(Order.desc("ranking"));
		criteria.setMaxResults(10);

		List<Filme> list = criteria.list(); 
		session.close();
		return list;
	}
	
	public List<Filme> carregarListaFilmesPorData() {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Filme.class);
		criteria.addOrder(Order.desc("data"));
		criteria.setMaxResults(10);

		List<Filme> list = criteria.list(); 
		session.close();
		return list;
	}
	
	public List<Filme> carregarListaFilmesPorCriterio(String titulo, int idGenero) {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Filme.class);
		criteria.addOrder(Order.asc("titulo"));
		
		if (titulo != null || !titulo.equals("")) {
			criteria.add(Restrictions.like("titulo", "%" + titulo + "%"));
		}
		
		if (idGenero != 0) {
			criteria.createCriteria("genero").add(Restrictions.eq("id", idGenero));
		}

		List<Filme> list = criteria.list(); 
		session.close();
		return list;
	}
	
	public void adicionarUsuario(Usuario usuario) {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		
		session.save(usuario);
		
		session.getTransaction().commit();
		session.close();
	}

	public List<Genero> carregarListaGenero() {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Genero.class);
		
		List<Genero> list = criteria.list(); 
		session.close();
		return list;
	}

	public Filme carregarFilmeMaisAssitido() {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Filme.class);
		criteria.addOrder(Order.desc("ranking"));
		criteria.setMaxResults(1);
		
		Filme maiorRanking = (Filme) criteria.list().get(0);
		
		session.close();
		return maiorRanking;
	}

	public Filme carregarFilmeEmDestaque() {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Filme.class);
		criteria.addOrder(Order.desc("data"));
		criteria.setMaxResults(1);
		
		Filme maiorRanking = (Filme) criteria.list().get(0);
		
		session.close();
		return maiorRanking;
	}

	public Filme carregarFilme(int id) {
		Session session = HibernateUtil.getSession();
		Filme filme = (Filme) session.load(Filme.class, id);
		
		Hibernate3BeanReplicator replicator = new Hibernate3BeanReplicator();
		/*
		Set<CollectionPropertyName> setProperties = new HashSet<CollectionPropertyName>(); 
		setProperties.add(new CollectionPropertyName(Comentario.class, "comentarios"));  
		setProperties.add(new CollectionPropertyName(Filme.class, "listFilme"));
		replicator.initCollectionPropertyNameSet(setProperties);
		*/
		Filme entidade = new Filme();
		entidade = replicator.deepCopy(filme);
		
		session.close();
		return entidade;
	}

	public void gravarNovoUsuario(String nome, String sobrenome, String email, String login, String senha, String csenha) throws ServletException, IOException {
		request.setAttribute("OMaisAssitido", carregarFilmeMaisAssitido());
		request.setAttribute("EmDestaque", carregarFilmeEmDestaque());
		request.setAttribute("ListaFilmesAssistidosPorRanking", carregarListaFilmesPorRanking());
		request.setAttribute("ListaFilmesAssistidosPorData", carregarListaFilmesPorData());
		request.setAttribute("ListaGenero", carregarListaGenero());
		
		if (!senha.equals(csenha)) {
			String nextJSP = "/paginas/cadastro/e_cadastro.jsp?erro=1";
			RequestDispatcher dispatcher = servletContext.getRequestDispatcher(nextJSP);
			dispatcher.forward(request,response);
			return;
		}
		
		Usuario usuario = new Usuario();
		usuario.setNome(nome);
		usuario.setSobrenome(sobrenome);
		usuario.setEmail(email);
		usuario.setLogin(login);
		usuario.setSenha(csenha);
		
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		session.save(usuario);
		session.getTransaction().commit();
		session.close();
		
		String nextJSP = "/paginas/cadastro/e_cadastro.jsp?erro=0";
		RequestDispatcher dispatcher = servletContext.getRequestDispatcher(nextJSP);
		dispatcher.forward(request,response);
	}

	public Usuario efetuarLogin(String login, String senha) {
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Usuario.class);
		criteria.add(Restrictions.eq("login", login));
		criteria.add(Restrictions.eq("senha", senha));
		
		List<Usuario> listUsuario = criteria.list(); 
		Usuario usuario = listUsuario.size() > 0 ? listUsuario.get(0) : null;
		
		session.close();
		return usuario;
	}

	public void adicionarComentario(int idUsuario, int idFilme, String comentario) {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		Usuario usuario = (Usuario) session.load(Usuario.class, idUsuario);
		Filme filme = (Filme) session.load(Filme.class, idFilme);
		
		Comentario c = new Comentario();
		c.setComentario(comentario);
		filme.addToComentario(c);
		
		usuario.addToComentario(c);
		
		session.update(usuario);
		session.update(filme);
		session.getTransaction().commit();
		session.close();
	}

}
